/**
 * Author shuqi
 * Rev
 * Date: 2021-08-16 16:33
 * <p>
 * Copyright (C) 2021 Seeyon, Inc. All rights reserved.
 * <p>
 * This software is the proprietary information of Seeyon, Inc.
 * Use is subject to license terms.
 * @company seeyon.com
 * @since V5 V7.1
 * @author shuqi
 */
package com.lagou;

import com.lagou.config.ServerConfig;
import com.lagou.config.ServletConfig;
import com.lagou.handler.AbstractHandler;
import com.lagou.handler.ContextHandler;
import com.lagou.handler.EngineHandler;
import com.lagou.handler.HostHandler;
import com.lagou.handler.WrapperHandler;
import org.dom4j.DocumentException;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * @description
 * @date 2021-08-16 16:33
 * @author Erekx
 */
public class Tomcat {

    public static void main(String[] args) throws IOException, DocumentException {
    	startMin();	
    }

    private static void startMin() throws IOException, DocumentException {
        //解析server.xml
        ServerConfig.ServiceConfig serverConfig = ServerConfig.initConfig();
        //解析web.xml
        ServletConfig.initConfig();
        //绑定engine->host->context->wrapper处理链
        AbstractHandler abstractHandler = handlerChannel();
        ServerSocket serverSocket = new ServerSocket(serverConfig.getPort());
        while(true){
            Socket socket = serverSocket.accept();
            InputStream inputStream = socket.getInputStream();
            int count = 0;
            while(count == 0){
                count = inputStream.available();
            }
            byte[] bytes = new byte[count];
            inputStream.read(bytes);
            //解析request
            Request request = getRequest(new String(bytes));
            Response response = new Response();
            OutputStream outputStream = socket.getOutputStream();
            response.setOutputStream(outputStream);
            abstractHandler.handleRequest(request, response);
            inputStream.close();
            outputStream.close();
            socket.close();
        }
    }

    /**
     * 绑定engine->host->context->wrapper处理链
     */
    private static AbstractHandler handlerChannel() {
        EngineHandler engineHandler = new EngineHandler();
        HostHandler hostHandler = new HostHandler();
        ContextHandler contextHandler = new ContextHandler();
        WrapperHandler wrapperHandler = new WrapperHandler();
        engineHandler.setNextHandler(hostHandler);
        hostHandler.setNextHandler(contextHandler);
        contextHandler.setNextHandler(wrapperHandler);
        return engineHandler;
    }

    /**
     * 解析请求
     * @param
     * @return
     */
    private static Request getRequest(String reqstr) throws IOException {
        String[] str = reqstr.split("\\n");
        Request request = new Request();
        String[] first = str[0].split(" ");
        request.setMethod(first[0]);
        String path = first[1];
        String[] split = path.split("/");
        String context = "/" + split[1];
        request.setContext(context);
        String url = "";
        if(split.length > 2) {
            for (int i = 2; i < split.length; i++) {
                url += "/" + split[i];
            }
        }
        if(url.length() == 0 ){
            url = "/";
        }
        request.setUrl(url);
        String[] second = str[1].split(" ");
        request.setHost(second[1].replaceAll("\r", ""));
        return request;
    }

}
